/**
 * Copyright &copy; 2012-2016 <a href="https://istep.lczyfz.com">Istep</a> All rights reserved.
 */
package com.lczyfz.istep.modules.scene.service;

import com.lczyfz.istep.common.constants.SceneConstants;
import com.lczyfz.istep.common.persistence.Page;
import com.lczyfz.istep.common.service.CrudService;
import com.lczyfz.istep.modules.openstack.api.neutron.impl.NetworksImpl;
import com.lczyfz.istep.modules.openstack.api.neutron.impl.PortImpl;
import com.lczyfz.istep.modules.openstack.api.neutron.impl.RouterImpl;
import com.lczyfz.istep.modules.openstack.api.neutron.impl.firewall.FireWallImpl;
import com.lczyfz.istep.modules.openstack.api.neutron.impl.firewall.FireWallPolicyImpl;
import com.lczyfz.istep.modules.openstack.api.neutron.impl.firewall.FireWallRuleImpl;
import com.lczyfz.istep.modules.openstack.api.neutron.impl.securitygroup.SecuritygroupImpl;
import com.lczyfz.istep.modules.openstack.api.neutron.model.Router;
import com.lczyfz.istep.modules.openstack.api.nova.impl.FlavorsImpl;
import com.lczyfz.istep.modules.openstack.api.nova.impl.VirtualMachineImpl;
import com.lczyfz.istep.modules.scene.dao.SceneCtfEnvironmentInstanceDao;
import com.lczyfz.istep.modules.scene.entity.SceneCtfEnvironmentInstance;
import com.lczyfz.istep.modules.scene.entity.SceneEnvironmentInstanceOs;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * CTF实验环境实例Service
 * @author dh
 * @version 2017-05-15
 */
@Service
@Transactional(readOnly = true)
public class SceneCtfEnvironmentInstanceService extends CrudService<SceneCtfEnvironmentInstanceDao, SceneCtfEnvironmentInstance> {

	public SceneCtfEnvironmentInstance get(String id) {
		return super.get(id);
	}
	
	public List<SceneCtfEnvironmentInstance> findList(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		return super.findList(sceneCtfEnvironmentInstance);
	}
	
	public Page<SceneCtfEnvironmentInstance> findPage(Page<SceneCtfEnvironmentInstance> page, SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		return super.findPage(page, sceneCtfEnvironmentInstance);
	}
	
	@Transactional(readOnly = false)
	public void save(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		super.save(sceneCtfEnvironmentInstance);
	}
	
	@Transactional(readOnly = false)
	public void delete(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		super.delete(sceneCtfEnvironmentInstance);
	}
	@Transactional(readOnly = false)
	public void  envInstanceRouterInsert (SceneEnvironmentInstanceOs sceneEnvironmentInstanceOs)
	{
		dao.envInstanceRouterInsert(sceneEnvironmentInstanceOs);
	}

	@Transactional(readOnly = false)
	public void  envInstanceNetworkInsert (SceneEnvironmentInstanceOs sceneEnvironmentInstanceOs)
	{
		dao.envInstanceNetworkInsert(sceneEnvironmentInstanceOs);


	}	@Transactional(readOnly = false)
		 public void  envInstanceSecurityGroupInsert (SceneEnvironmentInstanceOs sceneEnvironmentInstanceOs)
	{
		dao.envInstanceSecurityGroupInsert(sceneEnvironmentInstanceOs);


	}	@Transactional(readOnly = false)
		 public void  envInstanceVmTemplateInsert (SceneEnvironmentInstanceOs sceneEnvironmentInstanceOs)
	{
		dao.envInstanceVmTemplateInsert(sceneEnvironmentInstanceOs);
	}
	@Transactional(readOnly = false)
	public void  envInstancePortInsert (SceneEnvironmentInstanceOs sceneEnvironmentInstanceOs)
	{
		dao.envInstancePortInsert(sceneEnvironmentInstanceOs);
	}
	@Transactional(readOnly = false)
	public void  envInstanceFirewallInsert (SceneEnvironmentInstanceOs sceneEnvironmentInstanceOs)
	{
		dao.envInstanceFirewallInsert(sceneEnvironmentInstanceOs);
	}
	@Transactional(readOnly = false)
	public void  envInstanceFirewallRuleInsert (SceneEnvironmentInstanceOs sceneEnvironmentInstanceOs)
	{
		dao.envInstanceFirewallRuleInsert(sceneEnvironmentInstanceOs);
	}


	public List<SceneEnvironmentInstanceOs> findNetworkListByInstanceId(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		return dao.findNetworkListByInstanceId(sceneCtfEnvironmentInstance);
	}
	public List<SceneEnvironmentInstanceOs> findFirewallListByInstanceId(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		return dao.findFirewallListByInstanceId(sceneCtfEnvironmentInstance);
	}
	public List<SceneEnvironmentInstanceOs> findFirewallRuleListByInstanceId(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		return dao.findFirewallRuleListByInstanceId(sceneCtfEnvironmentInstance);
	}
	public List<SceneEnvironmentInstanceOs> findPortListByInstanceId(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		return dao.findPortListByInstanceId(sceneCtfEnvironmentInstance);
	}
	public List<SceneEnvironmentInstanceOs> findRouterListByInstanceId(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		return dao.findRouterListByInstanceId(sceneCtfEnvironmentInstance);
	}
	public List<SceneEnvironmentInstanceOs> findSecurityGroupListByInstanceId(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		return dao.findSecurityGroupListByInstanceId(sceneCtfEnvironmentInstance);
	}
	public List<SceneEnvironmentInstanceOs> findVmTemplateListByInstanceId(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) {
		return dao.findVmTemplateListByInstanceId(sceneCtfEnvironmentInstance);
	}
	public List<SceneEnvironmentInstanceOs> findOperateMachineByInstanceId(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance)
	{
		return  dao.findOperateMachineByInstanceId(sceneCtfEnvironmentInstance);
	}
	@Transactional(readOnly = false)
	public void deleteInstanceRouter(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance)
	{
		dao.deleteInstanceRouter(sceneCtfEnvironmentInstance);
	}
	@Transactional(readOnly = false)
	public void deleteInstanceNetwork(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance)
	{
		dao.deleteInstanceNetwork(sceneCtfEnvironmentInstance);

	}
	@Transactional(readOnly = false)
	public void deleteInstancePort(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance)
	{
		dao.deleteInstancePort(sceneCtfEnvironmentInstance);

	}
	@Transactional(readOnly = false)
	public void deleteInstanceSecurityGroup(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance)
	{
		dao.deleteInstanceSecurityGroup(sceneCtfEnvironmentInstance);

	}
	@Transactional(readOnly = false)
	public void deleteInstanceVmTemplate(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance)
	{
		dao.deleteInstanceVmTemplate(sceneCtfEnvironmentInstance);

	}
	@Transactional(readOnly = false)
	public void deleteInstanceFirewall(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance)
	{
		dao.deleteInstanceVmTemplate(sceneCtfEnvironmentInstance);

	}
	@Transactional(readOnly = false)
	public void deleteInstanceFirewallRule(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance)
	{
		dao.deleteInstanceVmTemplate(sceneCtfEnvironmentInstance);

	}

	@Transactional(readOnly = false)
	public void deleteInstance(SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance) throws RuntimeException,Exception
	{

		List<SceneEnvironmentInstanceOs> routerList=dao.findRouterListByInstanceId(sceneCtfEnvironmentInstance);
		List<SceneEnvironmentInstanceOs> vmTemplateList=dao.findVmTemplateListByInstanceId(sceneCtfEnvironmentInstance);
		List<SceneEnvironmentInstanceOs> securityGroupList=dao.findSecurityGroupListByInstanceId(sceneCtfEnvironmentInstance);
		List<SceneEnvironmentInstanceOs> firewallRuleList=dao.findFirewallRuleListByInstanceId(sceneCtfEnvironmentInstance);
		List<SceneEnvironmentInstanceOs> firewallList=dao.findFirewallListByInstanceId(sceneCtfEnvironmentInstance);

		List<SceneEnvironmentInstanceOs> networkList=dao.findNetworkListByInstanceId(sceneCtfEnvironmentInstance);
		for(int i=0;i<routerList.size();i++)
		{
			RouterImpl routerdemo = new RouterImpl();
			//删除路由表
			Router routertt = new Router();
			routertt.setRouters(null);
			routerdemo.updateRouter(routerList.get(i).getRouterId(), routertt);

			logger.debug("dingh===router=delete=" + routerList.get(i).getRouterId());

			if(routerList.get(i).getRouterId()!=null&&routerList.get(i).getSubnetId()!=null)
			{
				logger.debug("dingh===删除路由接口");

				routerdemo.removeRouterInterface(routerList.get(i).getRouterId(), routerList.get(i).getSubnetId(), SceneConstants.routerAndNetwork);
			}
			List<SceneEnvironmentInstanceOs> list= dao.findPortListById(routerList.get(i).getRouterId(), sceneCtfEnvironmentInstance.getId());

			for(SceneEnvironmentInstanceOs port:list)
			{
				logger.debug("dingh===删除路由接口2===");

				routerdemo.removeRouterInterface(routerList.get(i).getRouterId(), port.getPortId(), SceneConstants.routerAndRouter);

			}
			if(i==routerList.size()-1)
			{
				logger.debug("dingh===删除路由="+i);
				routerdemo.deleteRouter(routerList.get(i).getRouterId());
			}


		}
		for(SceneEnvironmentInstanceOs os: vmTemplateList)
		{
			logger.debug("dingh===vmTemplate=delete=" + os.getVmTemplateId());
			PortImpl portdemo = new PortImpl();
			portdemo.deletePort(os.getPortId());
			logger.debug("dingh===删除端口="+os.getPortId());

			VirtualMachineImpl nova = new VirtualMachineImpl();
			nova.deleteServer(os.getVmTemplateId());

			FlavorsImpl flavordemo = new FlavorsImpl();
			flavordemo.deleteFlavor(os.getFlavorRef());
			logger.debug("dingh===删除云主机类型=" + os.getFlavorRef());

		}
//		for(SceneEnvironmentInstanceOs os: portList)
//		{
//			logger.debug("dingh===port=delete=" + os.getPortId());
//
//			PortImpl portdemo = new PortImpl();
//			portdemo.deletePort(os.getPortId());
//		}
		for(SceneEnvironmentInstanceOs os: securityGroupList)
		{
			logger.debug("dingh===securityGroup=delete=" + os.getSecurityGroupId());

			SecuritygroupImpl securitygroupImpl = new SecuritygroupImpl();
			securitygroupImpl.deleteSecuritygroup(os.getSecurityGroupId());
		}

		for(SceneEnvironmentInstanceOs os:firewallList)
		{
			logger.debug("dingh===删除防火墙=");

			FireWallImpl impl = new FireWallImpl();
			impl.deleteFireWall(os.getFirewallId());

			FireWallPolicyImpl fwpolicy = new FireWallPolicyImpl();
			fwpolicy.deleteFireWallPolicy(os.getFirewallPolicyId());
		}
		for(SceneEnvironmentInstanceOs os:firewallRuleList)
		{
			logger.debug("dingh===删除防火墙规则=");

			FireWallRuleImpl fwrule = new FireWallRuleImpl();
			fwrule.deleteFireWallRule(os.getFirewallRuleId());
		}
		dao.deleteInstanceRouter(sceneCtfEnvironmentInstance);
		dao.deleteInstancePort(sceneCtfEnvironmentInstance);
		dao.deleteInstanceSecurityGroup(sceneCtfEnvironmentInstance);
		dao.deleteInstanceVmTemplate(sceneCtfEnvironmentInstance);
		dao.deleteInstanceFirewall(sceneCtfEnvironmentInstance);
		dao.deleteInstanceFirewallRule(sceneCtfEnvironmentInstance);
		dao.delete(sceneCtfEnvironmentInstance);

		//线程删除网络内部类
		class DeleteNetworkThread extends Thread{
			private String id;
			public DeleteNetworkThread(String id) {
				this.id=id;
			}

			public void run() {
				logger.debug("dingh===线程删除网络");

				try {
					Thread.sleep(1000*60*2);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				SceneCtfEnvironmentInstance sceneCtfEnvironmentInstance=new SceneCtfEnvironmentInstance();
				sceneCtfEnvironmentInstance.setId(id);
				List<SceneEnvironmentInstanceOs> networkList=dao.findNetworkListByInstanceId(sceneCtfEnvironmentInstance);
				for(SceneEnvironmentInstanceOs os: networkList)
				{
					logger.debug("dingh===network=delete=" + os.getNetworkId());
					NetworksImpl networkDemo=new NetworksImpl();
					networkDemo.deleteNetwork(os.getNetworkId());
				}
				deleteInstanceNetwork(sceneCtfEnvironmentInstance);
			}
		}


		Thread t1 = new DeleteNetworkThread(sceneCtfEnvironmentInstance.getId());
//		t1.start();
		ExecutorService pool= Executors.newCachedThreadPool();
//向线程池中提交两个线程
		pool.submit(t1);
//关闭线程池
		pool.shutdown();


//		deleteNetworkScheduleJob(sceneEnvironmentInstance);
	}
}